/*
* $Id: QueenBeeManager.java 288 2011-03-19 23:56:34Z volok-aleksej@yandex.ru $
*
* Copyright 2008-2011 by Volokitin Alexey
* All rights reserved
*
*/
package apiary.db.managers;

import java.util.Vector;
import java.util.Hashtable;
import java.io.*;

import apiary.Apiary;
import apiary.db.QueenBeeStore;
import apiary.db.QueenBeeStore.QueenBeeRecord;
import apiary.ui.journal.QueenBeeForm.QueenBeeValue;
import java.util.Enumeration;

/**
 * Queen bee database manager
 * @author lexus
 */
public class QueenBeeManager
{
    /** instance class */
    private static QueenBeeManager instance = null;
    /**
     * Gets instance class
     * @return instance class
     */
    protected static QueenBeeManager getInstance() {
        return instance;
    }
    
    /** Queen bee database */
    private QueenBeeStore queenBeeStore;
    /** maximal queen bee identificator */
    private int maxIdQueenBee;
    /** list of queen bees */
    private Vector dbQueenBee;
    /** list of breeds */
    private Hashtable breeds;

    /**
     * Constructor
     */
    public QueenBeeManager() {
        instance = this;
        queenBeeStore = new QueenBeeStore();
        dbQueenBee = new Vector();
        breeds = new Hashtable();
        readQueenBees();
        hashBreeds();
    }

    /**
     * Gets queen bees that's used by family
     * @param idFamily identificator of family
     * @return list of queen bees
     */
    protected Vector getQueenBees(int idFamily) {
        Vector qbees = new Vector();
        for(int i = 0; i < dbQueenBee.size(); i++) {
            QueenBeeRecord record = (QueenBeeRecord) dbQueenBee.elementAt(i);
            if(record.idFamily == idFamily)
                qbees.addElement(record);
        }
        return qbees;
    }

    protected QueenBeeRecord getQueenBee(int id) {
        for(int i = 0; i < dbQueenBee.size(); i++) {
            QueenBeeRecord record = (QueenBeeRecord) dbQueenBee.elementAt(i);
            if(record.idQueenBee == id)
                return record;
        }
        return null;
    }
    /**
     * Gets breeds of bee
     * @return list of breeds
     */
    protected Hashtable getBreeds() {
        return breeds;
    }

    /**
     * Adds queen bee at list.
     * Data will be parsed and created new queen bee object.
     * @param data binary data that describe queen bee
     */
    protected void addQueenBee(byte[] data) {
        QueenBeeRecord qBRecord = (QueenBeeRecord) queenBeeStore.getRecord();
        qBRecord.setData(data);
        dbQueenBee.addElement(qBRecord);
        if(maxIdQueenBee < qBRecord.idQueenBee)
            maxIdQueenBee = qBRecord.idQueenBee;
    }

    /**
     * Adds queen bee at list.
     * Data will be parsed and created new queen bee object.
     * @param queenBee binary data that describe queen bee
     */
    byte[] addQueenBee(QueenBeeValue queenBee) {
        maxIdQueenBee = nextIdQueenBee();
        QueenBeeRecord qBRecord = (QueenBeeRecord) queenBeeStore.getRecord();
        qBRecord.idQueenBee = maxIdQueenBee;
        ConvertData.QueenBeeValueToRecord(queenBee, qBRecord);
        dbQueenBee.addElement(qBRecord);
        return qBRecord.getData();
    }

    /**
     * Changes queen bee at list.
     * Converts queen bee to database format and changes at list.
     * @param id identificator queen bee
     * @param queen_bee queen bee value
     * @return binary data that describe queen bee
     */
    byte[] changeQueenBee(int id, QueenBeeValue queen_bee) {
        QueenBeeRecord qBRecord = getQueenBee(id);
        if(qBRecord == null)
            return null;
        ConvertData.QueenBeeValueToRecord(queen_bee, qBRecord);
        return qBRecord.getData();
    }

    /**
     * Delete queen bee from list.
     * @param id identificator of queen bee
     */
    byte[] deleteQueenBee(int id) {
        try {
            deleteQueenBeeFromList(id);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            DataOutputStream dos = new DataOutputStream(baos);
            dos.writeInt(id);
            return baos.toByteArray();
        } catch (IOException ex) {}
        return null;
    }

    /**
     * Clears the field in all queen bees of the family
     * @param id identificator of family
     */
    protected Vector deleteFamily(int idFamily) {
        Vector qbees = new Vector();
        for(int i = 0; i < dbQueenBee.size(); i++) {
            QueenBeeRecord record = (QueenBeeRecord) dbQueenBee.elementAt(i);
            if(record.idFamily == idFamily){
                record.idFamily = 0;
                qbees.addElement(record.getData());
            }
        }
        return qbees;
    }

    /**
     * Delete hive from list.
     * @param value binary data that describe hive
     */
    protected void deleteQueenBee(byte[] value) {
        try {
            ByteArrayInputStream bais = new ByteArrayInputStream(value);
            DataInputStream dis = new DataInputStream(bais);
            deleteQueenBeeFromList(dis.readInt());
        } catch (IOException ex) {}
    }

    /**
     * Changes queen bee at list.
     * Data will be parsed and changed queen bee object.
     * @param data binary data that describe queen bee
     */
    void changeQueenBee(byte[] data) {
        QueenBeeRecord qBRecord = (QueenBeeRecord) queenBeeStore.getRecord();
        qBRecord.setData(data);
        QueenBeeRecord queenBee = getQueenBee(qBRecord.idQueenBee);
        if(queenBee == null)
            return;
        queenBee.setData(data);
    }

    /**
     * Calculates next queen bee identificator
     * @return identificator
     */
    protected int nextIdQueenBee() {
        return maxIdQueenBee + 1;
    }

    /**
     * Resets all data in manager
     */
    protected void resetManager() {
        dbQueenBee.removeAllElements();
        maxIdQueenBee = 0;
        readQueenBees();
    }

    /**
     * Reads queen bee database
     */
    private void readQueenBees() {
        Enumeration queenBeeEnum = queenBeeStore.getRecordsEnumeration();
        do {
            if(!queenBeeEnum.hasMoreElements())
                break;
            QueenBeeRecord record = (QueenBeeRecord) queenBeeEnum.nextElement();
            dbQueenBee.addElement(record);
            if(maxIdQueenBee < record.idQueenBee)
                maxIdQueenBee = record.idQueenBee;
        } while(true);
    }
    
    /**
     * Fills breeds
     */
    private void hashBreeds() {
        Apiary apiary = Apiary.getInstance();
        breeds.put(new Integer(QueenBeeRecord.BREED_HYBRID),
                apiary.getLocaleString("BreedHybrid"));
        breeds.put(new Integer(QueenBeeRecord.BREED_ADAMII),
                apiary.getLocaleString("BreedAdamii"));
        breeds.put(new Integer(QueenBeeRecord.BREED_ADANSONII),
                apiary.getLocaleString("BreedAdansonii"));
        breeds.put(new Integer(QueenBeeRecord.BREED_ANATOLICA),
                apiary.getLocaleString("BreedAnatolica"));
        breeds.put(new Integer(QueenBeeRecord.BREED_ARMENIACA),
                apiary.getLocaleString("BreedArmeniaca"));
        breeds.put(new Integer(QueenBeeRecord.BREED_CAPENSIS),
                apiary.getLocaleString("BreedCapensis"));
        breeds.put(new Integer(QueenBeeRecord.BREED_CARNICA),
                apiary.getLocaleString("BreedCarnica"));
        breeds.put(new Integer(QueenBeeRecord.BREED_CARPATHICA),
                apiary.getLocaleString("BreedCarpathica"));
        breeds.put(new Integer(QueenBeeRecord.BREED_CAUCASICA),
                apiary.getLocaleString("BreedCaucasica"));
        breeds.put(new Integer(QueenBeeRecord.BREED_CECROPIA),
                apiary.getLocaleString("BreedCecropia"));
        breeds.put(new Integer(QueenBeeRecord.BREED_CYPRIA),
                apiary.getLocaleString("BreedCypria"));
        breeds.put(new Integer(QueenBeeRecord.BREED_FAREAST),
                apiary.getLocaleString("BreedFareast"));
        breeds.put(new Integer(QueenBeeRecord.BREED_IBERIENSIS),
                apiary.getLocaleString("BreedIberiensis"));
        breeds.put(new Integer(QueenBeeRecord.BREED_INTERMISSA),
                apiary.getLocaleString("BreedIntermissa"));
        breeds.put(new Integer(QueenBeeRecord.BREED_JEMENITICA),
                apiary.getLocaleString("BreedJemenitica"));
        breeds.put(new Integer(QueenBeeRecord.BREED_LAMARCKII),
                apiary.getLocaleString("BreedLamarckii"));
        breeds.put(new Integer(QueenBeeRecord.BREED_LIGUSTICA),
                apiary.getLocaleString("BreedLigustica"));
        breeds.put(new Integer(QueenBeeRecord.BREED_LITOREA),
                apiary.getLocaleString("BreedLitorea"));
        breeds.put(new Integer(QueenBeeRecord.BREED_MACEDONICA),
                apiary.getLocaleString("BreedMacedonica"));
        breeds.put(new Integer(QueenBeeRecord.BREED_MAJOR),
                apiary.getLocaleString("BreedMajor"));
        breeds.put(new Integer(QueenBeeRecord.BREED_MEDA),
                apiary.getLocaleString("BreedMeda"));
        breeds.put(new Integer(QueenBeeRecord.BREED_MELLIFERA),
                apiary.getLocaleString("BreedMellifera"));
        breeds.put(new Integer(QueenBeeRecord.BREED_MONTICOLA),
                apiary.getLocaleString("BreedMonticola"));
        breeds.put(new Integer(QueenBeeRecord.BREED_NUBICA),
                apiary.getLocaleString("BreedNubica"));
        breeds.put(new Integer(QueenBeeRecord.BREED_POMONELLA),
                apiary.getLocaleString("BreedPomonella"));
        breeds.put(new Integer(QueenBeeRecord.BREED_REMIPES),
                apiary.getLocaleString("BreedRemipes"));
        breeds.put(new Integer(QueenBeeRecord.BREED_RUTTNERI),
                apiary.getLocaleString("BreedRuttneri"));
        breeds.put(new Integer(QueenBeeRecord.BREED_SAHARIENSIS),
                apiary.getLocaleString("BreedSahariensis"));
        breeds.put(new Integer(QueenBeeRecord.BREED_SANETA),
                apiary.getLocaleString("BreedSaneta"));
        breeds.put(new Integer(QueenBeeRecord.BREED_SCUTELLATA),
                apiary.getLocaleString("BreedScutellata"));
        breeds.put(new Integer(QueenBeeRecord.BREED_SICULA),
                apiary.getLocaleString("BreedSicula"));
        breeds.put(new Integer(QueenBeeRecord.BREED_SOSSIMAI),
                apiary.getLocaleString("BreedSossimai"));
        breeds.put(new Integer(QueenBeeRecord.BREED_SYRIACA),
                apiary.getLocaleString("BreedSyriaca"));
        breeds.put(new Integer(QueenBeeRecord.BREED_UNICOLOR),
                apiary.getLocaleString("BreedUnicolor"));
    }

    private void deleteQueenBeeFromList(int id) {
        for(int i = 0; i < dbQueenBee.size(); i++) {
            QueenBeeRecord qb = (QueenBeeRecord) dbQueenBee.elementAt(i);
            if(qb.idParentQueenBee == id)
                qb.idParentQueenBee = 0;
            if(qb.idQueenBee == id) {
                dbQueenBee.removeElementAt(i);
                i--;
            }
        }
    }
}
